package com.zijidelu.luframework.plugins.tomlock.core.utils;

import com.zijidelu.luframework.plugins.tomlock.core.data.MethodParams;
import com.zijidelu.luframework.plugins.tomlock.core.exception.TomLockException;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * SpEL处理器。。
 *
 * @author ZIJIDELU
 * @datetime 2025/4/13 00:02
 */
public class TomLockSpELUtil {

    /**
     * 初始化SpEL上下文
     *
     * @param args       方法参数值
     * @param parameters 方法参数信息
     * @return SpEL上下文
     */
    public static StandardEvaluationContext initEvaluationContext(final Object[] args,
                                                                  final Parameter[] parameters) {
        // 构建SpEL上下文
        final StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext();

        // 设置SpEL上下文
        for (int i = 0; i < parameters.length; i++) {
            final Parameter parameter = parameters[i];

            // 将方法的参数写入SpEL上下文，参数名与参数值
            if (Objects.nonNull(args[i])) {
                standardEvaluationContext.setVariable(parameter.getName(), args[i]);
            }

        }

        return standardEvaluationContext;
    }

    /**
     * 初始化SpEL上下文
     *
     * @param paramsList 方法参数值列表
     * @return SpEL上下文
     */
    public static StandardEvaluationContext initEvaluationContext(final List<MethodParams> paramsList) {
        // 构建SpEL上下文
        final StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext();

        // 设置SpEL上下文

        for (MethodParams methodParams : paramsList) {
            if (Objects.nonNull(methodParams.getParamValue())) {

                standardEvaluationContext.setVariable(methodParams.getParamName(), methodParams.getParamValue());
            }
        }

        return standardEvaluationContext;
    }

    /**
     * 计算方法参数值列表
     *
     * @param dlParameters              分布式锁注解配置的SpEL参数
     * @param parser                    SpEL解析器
     * @param standardEvaluationContext SpEL上下文
     * @return 参数值列表
     */
    public static List<Object> calcMethodParamList(final String[] dlParameters,
                                                   final ExpressionParser parser,
                                                   final StandardEvaluationContext standardEvaluationContext) {
        final List<Object> paramList = new ArrayList<>();
        if (Objects.isNull(dlParameters)) {
            return paramList;
        }

        for (String param : dlParameters) {
            // 解析参数获取值
            final Object value = parser.parseExpression(param).getValue(standardEvaluationContext);

            if (Objects.isNull(value)) {
                throw new TomLockException(TomLockUtil.calcAnnoExceptionMessage("参数[%s]获取方法参数的数据为空", param));
            }

            paramList.add(value);
        }

        return paramList;
    }


}
